home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
CUGUK
/
PC_LIBS
/
C045.ZIP
/
BTREE.ARC
/
BTREEINC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-08
|
20KB
|
565 lines
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include "cstruct.h"
#include "datatype.h"
#include "ctrlkey.h"
#include "btutil.h"
#include "access.h"
#include "addkey.h"
#include "delkey.h"
#include "getkey.h"
#include "globals.h"
#include "names.h"
typedef enum {dolist, dodelete} actiontype;
typedef enum {cpage, npage} pagetype;
static void listkey(indexfile * nxfp);
static void add(void), find(void), linecust(void), inputcust(void);
static void outcust(custrec * custp);
static char * keyfromname(char * lname, char * fname);
static void listkey(indexfile * nxfp);
static void unsorted(actiontype action);
static char sbuf[64], ccode[16], keyn[26];
static custrec cust , *csp = &cust;
static custrec cust1, *csp1 = &cust1;
void update_record_count(void)
{
gotoxy(60,2);
printf("%5d active records", usedrecs(datfp));
}
static void outpage(tapage * pgptr, pagetype page)
{
char tmpstr[10];
int n;
tmpstr[9] = '\0';
n = page == cpage ? 0 : 9;
gotoxy(1,4+n);
printf("Items_On_Page: %4d, BackwdRef: %4d, Page No. %4d",
pgptr->itemsonpage, pgptr->bckwpageref,
((tapagerec *) pgptr)->pageref);
switch (pgptr->itemsonpage) {
case 16: strncpy(tmpstr, pgptr->itemarray[15].key, 9);
gotoxy(71, 9+n); printf("%-9s", tmpstr);
gotoxy(71,10+n); printf("%5d", pgptr->itemarray[15].dataref);
gotoxy(76,10+n); printf("%4d", pgptr->itemarray[15].pageref);
case 15: strncpy(tmpstr, pgptr->itemarray[14].key, 9);
gotoxy(61, 9+n); printf("%-9s", tmpstr);
gotoxy(61,10+n); printf("%5d", pgptr->itemarray[14].dataref);
gotoxy(66,10+n); printf("%4d", pgptr->itemarray[14].pageref);
case 14: strncpy(tmpstr, pgptr->itemarray[13].key, 9);
gotoxy(51, 9+n); printf("%-9s", tmpstr);
gotoxy(51,10+n); printf("%5d", pgptr->itemarray[13].dataref);
gotoxy(56,10+n); printf("%4d", pgptr->itemarray[13].pageref);
case 13: strncpy(tmpstr, pgptr->itemarray[12].key, 9);
gotoxy(41, 9+n); printf("%-9s", tmpstr);
gotoxy(41,10+n); printf("%5d", pgptr->itemarray[12].dataref);
gotoxy(46,10+n); printf("%4d", pgptr->itemarray[12].pageref);
case 12: strncpy(tmpstr, pgptr->itemarray[11].key, 9);
gotoxy(31, 9+n); printf("%-9s", tmpstr);
gotoxy(31,10+n); printf("%5d", pgptr->itemarray[11].dataref);
gotoxy(36,10+n); printf("%4d", pgptr->itemarray[11].pageref);
case 11: strncpy(tmpstr, pgptr->itemarray[10].key, 9);
gotoxy(21, 9+n); printf("%-9s", tmpstr);
gotoxy(21,10+n); printf("%5d", pgptr->itemarray[10].dataref);
gotoxy(26,10+n); printf("%4d", pgptr->itemarray[10].pageref);
case 10: strncpy(tmpstr, pgptr->itemarray[ 9].key, 9);
gotoxy(11, 9+n); printf("%-9s", tmpstr);
gotoxy(11,10+n); printf("%5d", pgptr->itemarray[ 9].dataref);
gotoxy(16,10+n); printf("%4d", pgptr->itemarray[ 9].pageref);
case 9: strncpy(tmpstr, pgptr->itemarray[ 8].key, 9);
gotoxy( 1, 9+n); printf("%-9s", tmpstr);
gotoxy( 1,10+n); printf("%5d", pgptr->itemarray[ 8].dataref);
gotoxy( 6,10+n); printf("%4d", pgptr->itemarray[ 8].pageref);
case 8: strncpy(tmpstr, pgptr->itemarray[7].key, 9);
gotoxy(71,6+n); printf("%-9s", tmpstr);
gotoxy(71,7+n); printf("%5d", pgptr->itemarray[7].dataref);
gotoxy(76,7+n); printf("%4d", pgptr->itemarray[7].pageref);
case 7: strncpy(tmpstr, pgptr->itemarray[6].key, 9);
gotoxy(61,6+n); printf("%-9s", tmpstr);
gotoxy(61,7+n); printf("%5d", pgptr->itemarray[6].dataref);
gotoxy(66,7+n); printf("%4d", pgptr->itemarray[6].pageref);
case 6: strncpy(tmpstr, pgptr->itemarray[5].key, 9);
gotoxy(51,6+n); printf("%-9s", tmpstr);
gotoxy(51,7+n); printf("%5d", pgptr->itemarray[5].dataref);
gotoxy(56,7+n); printf("%4d", pgptr->itemarray[5].pageref);
case 5: strncpy(tmpstr, pgptr->itemarray[4].key, 9);
gotoxy(41,6+n); printf("%-9s", tmpstr);
gotoxy(41,7+n); printf("%5d", pgptr->itemarray[4].dataref);
gotoxy(46,7+n); printf("%4d", pgptr->itemarray[4].pageref);
case 4: strncpy(tmpstr, pgptr->itemarray[3].key, 9);
gotoxy(31,6+n); printf("%-9s", tmpstr);
gotoxy(31,7+n); printf("%5d", pgptr->itemarray[3].dataref);
gotoxy(36,7+n); printf("%4d", pgptr->itemarray[3].pageref);
case 3: strncpy(tmpstr, pgptr->itemarray[2].key, 9);
gotoxy(21,6+n); printf("%-9s", tmpstr);
gotoxy(21,7+n); printf("%5d", pgptr->itemarray[2].dataref);
gotoxy(26,7+n); printf("%4d", pgptr->itemarray[2].pageref);
case 2: strncpy(tmpstr, pgptr->itemarray[1].key, 9);
gotoxy(11,6+n); printf("%-9s", tmpstr);
gotoxy(11,7+n); printf("%5d", pgptr->itemarray[1].dataref);
gotoxy(16,7+n); printf("%4d", pgptr->itemarray[1].pageref);
case 1: strncpy(tmpstr, pgptr->itemarray[0].key, 9);
gotoxy( 1,6+n); printf("%-9s", tmpstr);
gotoxy( 1,7+n); printf("%5d", pgptr->itemarray[0].dataref);
gotoxy( 6,7+n); printf("%4d", pgptr->itemarray[0].pageref);
break;
}
}
static void clearcust(void)
{
memset (csp, 0, sizeof(custrec));
}
static void inputcust(void)
{
static char charset[] = "\x05\x09\x0d\x18\x1a";
int h, tc;
h = 1;
do {
switch (h) {
case 1 : tc = inputstr(csp->custcode, 15, 14, 5, charset);
break;
case 2 : tc = inputstr(csp->entrydate, 8, 37, 5, charset);
break;
case 3 : tc = inputstr(csp->firstname, 15, 14, 7, charset);
break;
case 4 : tc = inputstr(csp->lastname, 30, 42, 7, charset);
break;
case 5 : tc = inputstr(csp->company, 40, 14, 9, charset);
break;
case 6 : tc = inputstr(csp->addr1, 40, 14, 10, charset);
break;
case 7 : tc = inputstr(csp->addr2, 40, 14, 11, charset);
break;
case 8 : tc = inputstr(csp->phone, 15, 14, 13, charset);
break;
case 9 : tc = inputstr(csp->phoneext, 5, 42, 13, charset);
break;
case 10 : tc = inputstr(csp->remarks1, 40, 14, 15, charset);
break;
case 11 : tc = inputstr(csp->remarks2, 40, 14, 16, charset);
break;
case 12 : tc = inputstr(csp->remarks3, 40, 14, 17, charset);
break;
}
if ((tc == TAB) || (tc == RET) || (tc == CTLX))
h = h % 12 + 1;
else if (tc == CTLE)
h = (h + 10) % 12 + 1;
} while ( ((tc != RET) || (h != 1)) && (tc != CTLZ) );
}
static void outcust(custrec * custptr)
{
gotoxy(14, 5); printf("%-15s", custptr->custcode);
gotoxy(37, 5); printf("%s", custptr->entrydate); clreol();
gotoxy(14, 7); printf("%-15s", custptr->firstname);
gotoxy(42, 7); printf("%-15s", custptr->lastname); clreol();
gotoxy(14, 9); printf("%s", custptr->company); clreol();
gotoxy(14, 10); printf("%s", custptr->addr1); clreol();
gotoxy(14, 11); printf("%s", custptr->addr2); clreol();
gotoxy(14, 13); printf("%s", custptr->phone);
gotoxy(42, 13); printf("%s", custptr->phoneext); clreol();
gotoxy(14, 15); printf("%s", custptr->remarks1); clreol();
gotoxy(14, 16); printf("%s", custptr->remarks2); clreol();
gotoxy(14, 17); printf("%s", custptr->remarks3); clreol();
}
static char * keyfromname(char * lastnm, char * firstnm)
{
unsigned n;
memset(buffer, ' ', 25);
buffer[25] = '\0';
n = (strlen(lastnm) >= 15 ? 15 : strlen(lastnm));
memcpy(buffer, lastnm, n);
n = (strlen(firstnm) >= 10 ? 10 : strlen(firstnm));
memcpy (buffer+15, firstnm, n);
return (strupr(buffer));
}
static void linecust()
{
gotoxy(1,24);
printf("Next entry: %8s %12s %15s", csp->custcode,
csp->firstname, csp->lastname);
}
void create()
{
int i, datref;
char ch;
tapage * addptr;
clearcust();
while (TRUE) {
sprintf(csp->custcode, "%c%04d", random(4)+'A', random(5000));
strcpy(csp->entrydate, edates[random(MAXDATES)]);
strcpy(csp->firstname, fnames[random(MAXFNAMES)]);
strcpy(csp->lastname, lnames[random(MAXLNAMES)]);
strcpy(ccode, csp->custcode);
if ((datref = findkey (cnxfp, ccode)) != NULL) {
linecust();
getrec(datfp, datref, (char *) csp1);
sprintf(sbuf, "Duped! Recno: %d is %s %s %s "
"<Ret>: continue, 'q': quit",
datref, csp1->custcode, csp1->firstname, csp1->lastname);
if ((ch = select (sbuf, "qQ\x0d")) != RET) break;
}
else {
linecust();
sprintf(sbuf, "Code unique - <Ret> to add, <sp> to skip, or 'q' to quit");
if ((ch = select(sbuf, "qQ\x20\x0d")) == RET) {
datref = addrec(datfp, (char *) csp);
addptr = addkey (cnxfp, datref, csp->custcode);
clearwindow(1,4,80,20);
outpage(addptr, cpage);
strcpy (keyn, keyfromname(csp->lastname, csp->firstname));
addptr = addkey (nnxfp, datref, keyn);
outpage(addptr, npage);
gotoxy(1, 2);
printf("Entry added %8s %12s %15s as record %d",
csp->custcode, csp->firstname,
csp->lastname, usedrecs(datfp));
clreol();
}
else if (ch == 'q' || ch == 'Q')
break;
}
}
clearwindow(1,2, 80,24);
}
void reconstruct()
{
int ld, recno;
char keyn[26];
gotoxy(1,23);
printf("Reconstructing indices..."); clreol();
/* first, set the datafile header aright, just in case.. */
datfp->numrecs = filelen(datfp);
datfp->firstfree = -1;
datfp->numberfree = 0;
memcpy(&tarecbuf, datfp, 12);
putrec(datfp, 0, (char *) &tarecbuf);
ld = datfp->numrecs - 1;
for (recno = 1; recno <= ld; recno++) {
getrec(datfp, recno, (char *) csp);
if (csp->custstatus == 0) { /* if not deleted and custcode
is unique, then add the keys */
if (addkey(cnxfp, recno, csp->custcode) != NULL) {
strcpy(keyn, keyfromname (csp->lastname, csp->firstname));
addkey(nnxfp, recno, keyn);
}
}
else
deleterec(datfp, recno);
if (recno % 100 == 0) {
gotoxy(40,23);
printf("%4d indices reconstructed", recno);
}
}
}
static void add(void)
{
int datref;
char ch;
csp = &cust;
memset (csp, '\0', sizeof(custrec));
inputcust();
strcpy(ccode, csp->custcode);
if ((datref = findkey (cnxfp, ccode)) != NULL) {
sprintf(sbuf, "Duplicate code at recno %d - <Sp> to continue", datref);
select (sbuf, " ");
}
else {
ch = select ("Customer code OK - Return to ADD, Sp-bar to cancel",
"\x20\x0d");
if (ch == RET) {
datref = addrec(datfp, (char *) csp);
addkey (cnxfp, datref, csp->custcode);
strcpy (keyn, keyfromname(csp->lastname, csp->firstname));
addkey (nnxfp, datref, keyn);
}
}
}
static void find(void)
{
int recno, caseno, codevalid;
char ch, tc;
char pnm[26], pcode[16], firstnm[16], lastnm[31];
if (usedrecs(datfp) > 0) {
ccode[0] = '\0';
do {
tc = inputstr(ccode, 15, 14, 5, "\x0d\x1a");
if (strlen(ccode) > 0)
if ((recno = findkey(cnxfp, ccode)) != NULL) {
getrec(datfp, recno, (char *) csp);
outcust(csp);
}
else
select("Customer code not found.. <Sp> to continue","\x20");
} while (ccode[0] != '\0' && recno == 0);
if (ccode[0] == '\0') {
caseno = 1;
firstnm[0] = '\0';
lastnm[0] = '\0';
do {
switch (caseno) {
case 1 : tc = inputstr(firstnm, 15, 14, 7, "\x09\x0d\x1a");
break;
case 2 : tc = inputstr(lastnm, 30, 42, 7, "\x09\x0d\x1a");
break;
}
if (tc == TAB || tc == RET)
caseno = 3 - caseno;
} while (tc != CTLZ && (tc != RET || caseno != 1));
strcpy (keyn, keyfromname(lastnm, firstnm));
if ((recno = searchkey(nnxfp, keyn)) == NULL)
recno = prevkey(nnxfp, keyn);
do {
getrec(datfp, recno, (char *) csp);
outcust(csp);
ch = select("Find: N)ext, P)revious, Q)uit", "NnPpQq");
if ((ch = toupper(ch)) == 'N')
recno = nextkey(nnxfp, keyn);
else if (ch == 'P')
recno = prevkey(nnxfp, keyn);
} while (ch != 'Q');
} /* if custcode[0] = '\0' */
ch = select("Find: E)dit, D)elete, L)ist, Q)uit", "edlqEDLQ");
if ( (ch = toupper(ch)) == 'E' ) {
strcpy (pcode, csp->custcode);
strcpy (pnm, keyfromname(csp->lastname, csp->firstname));
do {
clearwindow (1,23, 80,23);
inputcust();
/*
* After editing, if custcode hasn't changed, the code is considered
* valid. Otherwise, if the custcode does not already exist, it is
* considered valid.
*/
if (strcmp (csp->custcode, pcode) == 0)
codevalid = TRUE;
else {
strcpy (ccode, csp->custcode);
if (findkey (cnxfp, ccode)) {
codevalid = FALSE;
select("Duplicate customer code .. Press space bar","\x20");
}
else {
codevalid = TRUE;
select("Customer code unique .. Press space bar","\x20");
}
}
} while (!codevalid);
putrec (datfp, recno, (char *) csp);
if (strcmp (csp->custcode, ccode) != 0) {
deletekey (cnxfp, recno, pcode);
addkey (cnxfp, recno, csp->custcode);
}
strcpy (keyn, keyfromname (csp->lastname, csp->firstname));
if (strcmp (keyn, pnm) != 0) {
deletekey (nnxfp, recno, pnm);
addkey (nnxfp, recno, keyn);
}
}
else if (ch == 'D') {
deletekey (cnxfp, recno, csp->custcode);
strcpy (keyn, keyfromname (csp->lastname, csp->firstname));
deletekey (nnxfp, recno, keyn);
deleterec (datfp, recno);
} /* if (ch = toupper(ch)) == 'E' */
else if (ch == 'L') {
clearwindow(1,2, 80,22);
recno = prevkey(nnxfp, keyn);
listkey(nnxfp);
}
}
else beep();
}
void update(void)
{
char ch;
ch = select("Update : A)dd, F)ind, Q)uit", "AaFfQq");
while ((ch = toupper(ch)) != 'Q') {
clearwindow(1,2, 80,22);
if (ch == 'F') {
outform();
find();
}
else if (ch == 'A') {
outform();
add();
}
update_record_count();
ch = select("Update : A)dd, F)ind, Q)uit", "AaFfQq");
}
clearform();
}
static void listkey(indexfile * nxfp)
{
int recno, l;
char ch;
char name[36], startcode[26];
if ((recno = nextkey(nxfp, ccode)) == NULL) {
beep();
return;
}
getrec(datfp, recno, (char *) csp);
strcpy(startcode, csp->custcode);
l = 4;
do {
if (kbhit())
if ((ch = getch()) == ESC)
break;
strcpy(name, csp->lastname);
if (strlen(csp->firstname)) {
strcat(name, ", ");
strcat(name, csp->firstname);
}
csp->company[30] = '\0';
if (l == 22) {
ch = select("<Return> to continue, <ESC> to abort", "\x0d\x1b");
if (ch == ESC)
return;
select("Press ESC to abort", "");
clearwindow(1, 4, 80, 21);
l = 4;
}
gotoxy(1, l++);
printf("%-10s %-35s %-30s", csp->custcode, name, csp->company);
recno = nextkey(nxfp, ccode);
getrec(datfp, recno, (char *) csp);
} while (strcmp(startcode, csp->custcode) != 0);
select("Press Return", "\x0d");
}
static void unsorted(actiontype action)
{
int recno, d, l, ld;
char ch;
char name[36];
if ((ld = filelen(datfp) - 1) == 0) {
beep();
return;
}
d = 0;
l = 4;
while (TRUE) {
recno = 0;
while ( recno == 0 && ++d <= ld ) {
getrec(datfp, d, (char *) csp);
recno = (csp->custstatus == 0) ? d : 0;
}
if (recno == 0) break;
strcpy(name, csp->lastname);
if (strlen(csp->firstname)) {
strcat(name, ", ");
strcat(name, csp->firstname);
}
if (l == 22) {
update_record_count();
ch = select("<Return> to continue, <ESC> to abort","\x0d\x1b");
if (ch == ESC)
return;
clearwindow(1, 4, 80, 21);
l = 4;
}
gotoxy(1, l);
if (action == dodelete) {
deletekey(cnxfp, recno, csp->custcode);
strcpy(keyn, keyfromname(csp->lastname, csp->firstname));
deletekey(nnxfp, recno, keyn);
deleterec(datfp, recno);
printf("%-10s %-35s %-30s", csp->custcode, name, "deleted");
}
else
printf("%-10s %-35s %-30s", csp->custcode, name, csp->company);
l++;
}
select("Press return", "\x0d");
}
void list(void)
{
char ch;
ch = select("Sort by : C)ode, N)ame, U)nsorted", "cnuCNU");
if ((ch = toupper(ch)) == 'C') {
clearkey(cnxfp);
listkey(cnxfp);
}
else if (ch == 'N') {
clearkey(nnxfp);
listkey(nnxfp);
}
else
unsorted(dolist);
}
void delete(void)
{
unsorted(dodelete);
}